﻿/*
 * Copyright © 2020, Wuxi Safover Intelligent Technology Co., Ltd. All rights reserved.
 * 
 * 无锡安永智能科技有限公司版权所有，未经许可，不得用于商业用途
 * 
 * Visit: https://www.safover.com/ 
 */

using System;
using Safover.LidarCollector.Models;
using Safover.Lidar.DataContract;

namespace Safover.LidarCollector.Managers
{
    internal abstract class PeriodicScanParams
    {
        /// <summary>
        /// 全局扫描配置
        /// </summary>
        internal LidarWorkMode LidarWorkMode { get; set; }

        /// <summary>
        /// 周期扫描模式，数据类型有误；
        /// TODO：Type should be LidarScanMode
        /// </summary>
        internal abstract LidarWorkMode PeriodicScanLidarWorkMode { get; }

        /// <summary>
        /// 周期扫描开始时间
        /// </summary>
        internal DateTime UtcPeriodicScanStartTime { get; }

        internal PeriodicScanParams(LidarWorkMode lidarWorkMode)
        {
            LidarWorkMode = lidarWorkMode;

            UtcPeriodicScanStartTime = DateTime.UtcNow;
        }

        public override string ToString()
        {
            return $"{LidarWorkMode}-{PeriodicScanLidarWorkMode}";
        }
    }

    /// <summary>
    /// 幅度扫描（V-Scan 和 H-Scan）基类
    /// </summary>
    internal abstract class PeriodicRangeScanParams : PeriodicScanParams 
    {
        internal float StartAngle { get; set; }
        internal float RangeAngle { get; set; }
        internal float FixedAngle { get; set; }
        internal float StepAngle { get; set; }

        internal TimeSpan PeriodScanEndDelayDuration { get; set; }

        protected PeriodicRangeScanParams(LidarWorkMode lidarWorkMode, float startAngle, float rangeAngle, float fixedAngle, float stepAngle, TimeSpan periodScanEndDelayDuration) : base(lidarWorkMode)
        {
            StartAngle = startAngle;
            RangeAngle = rangeAngle;
            FixedAngle = fixedAngle;
            StepAngle = stepAngle;

            PeriodScanEndDelayDuration = periodScanEndDelayDuration;
        }

        public override string ToString()
        {
            return $"{base.ToString()}: Start={StartAngle}, Range={RangeAngle}, Step={StepAngle}, Fixed={FixedAngle}.";
        }
    }

    internal class PeriodicVerticalRangeScanParams : PeriodicRangeScanParams
    {
        internal override LidarWorkMode PeriodicScanLidarWorkMode => LidarWorkMode.Vertical;

        internal float VerticalStartAngle => StartAngle;

        internal VerticalBlindSectorConfig[] BlindSectorConfigs { get; set; }

        public PeriodicVerticalRangeScanParams(LidarWorkMode lidarWorkMode, float startAngle, float rangeAngle, float fixedAngle, float stepAngle, VerticalBlindSectorConfig[] blindSectorConfigs, TimeSpan periodScanEndDelayDuration) : base(lidarWorkMode, startAngle, rangeAngle, fixedAngle, stepAngle,  periodScanEndDelayDuration)
        {
            BlindSectorConfigs = blindSectorConfigs;
        }
    }

    internal class PeriodicHorizontalRangeScanParams : PeriodicRangeScanParams
    {
        internal override LidarWorkMode PeriodicScanLidarWorkMode => LidarWorkMode.Horizontal;

        internal float HorizontalStartAngle => StartAngle;

        internal HorizontalBlindSectorConfig[] BlindSectorConfigs { get; set; }

        public PeriodicHorizontalRangeScanParams(LidarWorkMode lidarWorkMode, float startAngle, float rangeAngle, float fixedAngle, float stepAngle, HorizontalBlindSectorConfig[] blindSectorConfigs, TimeSpan periodScanEndDelayDuration) : base(lidarWorkMode, startAngle, rangeAngle, fixedAngle, stepAngle, periodScanEndDelayDuration)
        {
            BlindSectorConfigs = blindSectorConfigs;
        }
    }


    internal abstract class PeriodicUnmovableScanParams : PeriodicScanParams 
    {
        internal float FixedVerticalAngle { get; set; }

        internal float FixedHorizontalAngle { get; set; }

        protected PeriodicUnmovableScanParams(LidarWorkMode lidarWorkMode, float fixedVerticalAngle, float fixedHorizontalAngle) : base(lidarWorkMode)
        {
            FixedVerticalAngle = fixedVerticalAngle;
            FixedHorizontalAngle = fixedHorizontalAngle;
        }

        public override string ToString()
        {
            return $"{base.ToString()}: Fixed Vertical={FixedVerticalAngle}, Fixed Horizontal={FixedHorizontalAngle}.";
        }
    }

    internal class PeriodicFixedScanParams : PeriodicUnmovableScanParams
    {
        public TimeSpan SingleScanEndDelayDuration { get; set; }

        internal override LidarWorkMode PeriodicScanLidarWorkMode => LidarWorkMode.Fixed;

        public PeriodicFixedScanParams(LidarWorkMode lidarWorkMode, float fixedVerticalAngle, float fixedHorizontalAngle, TimeSpan singleScanEndDelayDuration) : base(lidarWorkMode, fixedVerticalAngle, fixedHorizontalAngle)
        {
            SingleScanEndDelayDuration = singleScanEndDelayDuration;
        }
    }


    internal class PeriodicUnderwayScanParams : PeriodicUnmovableScanParams
    {
        internal override LidarWorkMode PeriodicScanLidarWorkMode => LidarWorkMode.Underway;

        //internal string LastFolderNameForUnderwayMode { get; set; }

        public PeriodicUnderwayScanParams(LidarWorkMode lidarWorkMode, float fixedVerticalAngle, float fixedHorizontalAngle/*, string lastFolderNameForUnderwayMode*/) : base(lidarWorkMode, fixedVerticalAngle, fixedHorizontalAngle)
        {
            //LastFolderNameForUnderwayMode = lastFolderNameForUnderwayMode;
        }
    }
}
